package com.alipay.rebate.shop.service.customer.impl;

import com.alibaba.fastjson.JSON;
import com.alipay.rebate.shop.configuration.shiro.token.WeixinToken;
import com.alipay.rebate.shop.constants.*;
import com.alipay.rebate.shop.dao.mapper.*;
import com.alipay.rebate.shop.exceptoin.*;
import com.alipay.rebate.shop.helper.*;
import com.alipay.rebate.shop.model.*;
import com.alipay.rebate.shop.pojo.common.ResponseResult;
import com.alipay.rebate.shop.pojo.dingdanxia.DingdanxiaLink;
import com.alipay.rebate.shop.pojo.dingdanxia.DingdanxiaRsp;
import com.alipay.rebate.shop.pojo.dingdanxia.PddConvertReq;
import com.alipay.rebate.shop.pojo.mobilecode.SendSmsResponse;
import com.alipay.rebate.shop.pojo.pdd.PddConvertRes;
import com.alipay.rebate.shop.pojo.pdd.PddConvertResponse;
import com.alipay.rebate.shop.pojo.pdtframework.ProductRepoChoice;
import com.alipay.rebate.shop.pojo.pdtframework.ProductRepoChoiceRsp;
import com.alipay.rebate.shop.pojo.taobao.TpwdRequest;
import com.alipay.rebate.shop.pojo.user.TaobaoAuthRsp;
import com.alipay.rebate.shop.pojo.user.TokenRsp;
import com.alipay.rebate.shop.pojo.user.customer.*;
import com.alipay.rebate.shop.pojo.user.product.ActivityProductCondition;
import com.alipay.rebate.shop.pojo.user.product.CheckActivityConditionRsp;
import com.alipay.rebate.shop.pojo.usergrade.UserGradeRsp;
import com.alipay.rebate.shop.service.common.AbstractUserService;
import com.alipay.rebate.shop.service.customer.CustomerProductService;
import com.alipay.rebate.shop.service.customer.CustomerUserService;
import com.alipay.rebate.shop.utils.*;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.gson.Gson;
import com.taobao.api.response.TbkScPublisherInfoSaveResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;

@Service
@Transactional
public class CustomerUserServiceImpl extends AbstractUserService implements CustomerUserService {

  private Logger logger = LoggerFactory.getLogger(CustomerUserServiceImpl.class);

  @Autowired
  private StringRedisTemplate stringRedisTemplate;
  @Resource
  private UserIncomeMapper userIncomeMapper;
  @Resource
  private OrdersMapper ordersMapper;
  @Resource
  private ActivityProductMapper activityProductMapper;
  @Resource
  private ActivityBrowseProductMapper activityBrowseProductMapper;
  @Resource
  private BrowseAdMapper browseAdMapper;
  @Resource
  private AppSkMapper appSkMapper;
  @Resource
  private CustomerProductService customerProductService;
  @Resource
  private OrderActivityRecordMapper orderActivityRecordMapper;
  @Resource
  private TaskDoRecordMapper taskDoRecordMapper;
  @Resource
  private TaskSettingsMapper taskSettingsMapper;
  @Resource
  private LuckyMoneyHelper luckyMoneyHelper;
  @Resource
  private UserHelper userHelper;
  @Resource
  private UserGradeHelper userGradeHelper;
  @Resource
  private MobileCodeInformationMapper informationMapper;
  @Resource
  private MobileCodeInformationHelper informationHelper;
  @Resource
  private UserMapper userMapper;
  @Resource
  UserJdPidHelper userJdPidHelper;
  CopyOnWriteArrayList<ConcurrentHashMap<String,Long>> ipList = new CopyOnWriteArrayList<>();
  private Gson gson = new Gson();

  public void phoneRegister(UserRequest userRequest, HttpServletRequest request) {
    logger.debug("phone register");
    // 到数据库查看用户是否已经存在
    User u = userMapper.selectUserByPhone(userRequest.getUserPhone());
    // 如果是手机号注册（非微信注册）, 则检查手机号是否已经被注册
    if (userRequest.getOpenId() == null && u != null) {
      logger.debug("user with phone {} already exists", userRequest.getUserPhone());
      throw new PhoneAlreadyRegistedException();
    }
    User user = new User();
    user.setPhone(userRequest.getUserPhone());
    user.setAreaCode(userRequest.getAreaCode());
    user.setUserNickName(userRequest.getUserNickName());
    String plainText = userRequest.getPassword();
    user.setUserHeadImage(UserContant.HEAD_IMG_URL);
    user.setUserPassword(EncryptUtil.encryptPassword(plainText));
    // 设置用户公共注册参数并保存
    UserBuilder.setRegisterCommonField(user,request);
    logger.debug("user is : {}",user);
    userMapper.insertSelective(user);
    // 注册送红包
    luckyMoneyHelper.giveLuckyMoneyCoupon(user.getUserId());
  }

  public void weixinRegister(UserRequest userRequest,HttpServletRequest request) {
    // 到数据库查看用户是否已经存在
    User u = userMapper.selectUserByPhone(userRequest.getUserPhone());
    // 新建用户对象用于更新或者其他操作
    User user = new User();
    user.setUserNickName(userRequest.getUserNickName());
    user.setUserHeadImage(userRequest.getHeadImageUrl());
    String plainText = userRequest.getPassword();
    user.setUserPassword(EncryptUtil.encryptPassword(plainText));
    user.setOpenId(userRequest.getOpenId());
    // 手机号已经被注册
    if (u != null) {
      logger.debug("phone has been registered");
      user.setUserId(u.getUserId());
      userMapper.updateUser(user);
      // 如果之前没有授权过微信, 那么进行奖励
      if(StringUtils.isEmpty(u.getOpenId())){
        // 如果有新人任务配置, 那么添加新人任务完成记录和奖励用户
        addNewUserTaskDoAndUserIncomeRecord(TaskSettingsConstant.BIND_WECHAT_ACCOUNT,
            user.getUserId(), UserIncomeConstant.WETCHAT_AUTH_AWAED_TYPE);
      }
      return ;
    }
    logger.debug("register a new user");
    user.setPhone(userRequest.getUserPhone());
    user.setAreaCode(userRequest.getAreaCode());
    // 设置用户公共注册参数并保存
    UserBuilder.setRegisterCommonField(user,request);
    userMapper.insertSelective(user);
    // 直接微信注册
    // 如果有新人任务配置, 那么添加新人任务完成记录和奖励用户
    addNewUserTaskDoAndUserIncomeRecord(TaskSettingsConstant.BIND_WECHAT_ACCOUNT,
        user.getUserId(), UserIncomeConstant.WETCHAT_AUTH_AWAED_TYPE);
    // 注册送红包
    luckyMoneyHelper.giveLuckyMoneyCoupon(user.getUserId());
  }

  public void h5Register(UserRequest userRequest,HttpServletRequest request) {
    // 根据推广人的id，到数据库中找到推广人的id
    User inviteUser = userMapper.selectById(userRequest.getParentUserId());
    logger.debug("invite user message is : {}", inviteUser);
    // 到数据库查看用户是否已经存在
    User u = userMapper.selectUserByPhone(userRequest.getUserPhone());
    // 如果是手机号注册（非微信注册）, 则检查手机号是否已经被注册
    if (u != null) {
      logger.debug("user with phone {} already exists", userRequest.getUserPhone());
      throw new PhoneAlreadyRegistedException();
    }
    // 新建一个用户
    User user = new User();
    user.setOpenId(userRequest.getOpenId());
    user.setPhone(userRequest.getUserPhone());
    user.setAreaCode(userRequest.getAreaCode());
    user.setUserNickName(userRequest.getUserNickName());
    user.setUserRegisterIp(IpUtil.getIpAddress(request));
    String plainText = userRequest.getPassword();
    user.setUserPassword(EncryptUtil.encryptPassword(plainText));
    user.setUserHeadImage(UserContant.HEAD_IMG_URL);
    if (inviteUser != null) {
      user.setParentUserId(inviteUser.getUserId());
      user.setParentUserName(inviteUser.getParentUserName());
    }
    UserBuilder.setRegisterCommonField(user,request);
    logger.debug("new user is : {}", user);
    userMapper.insertSelective(user);
    luckyMoneyHelper.giveLuckyMoneyCoupon(user.getUserId());
    // 如果推荐人不为空，那么推荐人粉丝数加 1
    if(inviteUser != null){
      logger.debug("inviteUser TotalFansNum add 1");
      logger.debug("inviteUser StraightFansNum add 1");
      Integer currentTotalFansNum = inviteUser.getTotalFansNum();
      Integer currentStraightFansNum = inviteUser.getStraightFansNum();
      logger.debug("currentTotalFansNum and currentStraightFansNum is: {}, {}"
          ,currentTotalFansNum,currentStraightFansNum);
      userMapper.plusTotalFanAndStraightFanNum(1,1,inviteUser.getUserId());
      // 如果推荐人上级还有推荐人, 那么这个上上级的总粉丝数也加 1
      if(inviteUser.getParentUserId() != null){
        User upperInviteUser = userMapper.selectById(inviteUser.getParentUserId());
        logger.debug("upperInviteUser TotalFansNum add 1");
        logger.debug("upperInviteUser StraightFansNum add 1");
        if(upperInviteUser != null){
          userMapper.plusTotalFanAndStraightFanNum(1,null,inviteUser.getParentUserId());
        }
      }
    }
  }

  private void addNewUserTaskDoAndUserIncomeRecord(Integer subType, Long userId,Integer incomeType){
//    TaskSettings taskSettings = taskSettingsMapper.selectUseSettingsBySubType(subType);
    List<TaskDoRecord> dbTaskDoRecords = taskDoRecordMapper.selectNewUserRecordBySubType(userId, subType);
    logger.debug("dbTaskDoRecord is :{}",dbTaskDoRecords);
    if (ListUtil.isEmptyList(dbTaskDoRecords)){
      TaskSettings taskSettings = taskSettingsMapper.selectUseSettingsBySubType(subType);
      if(taskSettings == null) {
        // 新人授权任务没开启，也要插入用户的授权记录到数据库,不奖励
        TaskDoRecord taskDoRecord = TaskDoRecordBuilder
                .buildTaskDoRecord(TaskSettingsConstant.NEW_USER_TASK,subType, userId);
        taskDoRecordMapper.insertSelective(taskDoRecord);
        return;
      }
      logger.debug("taskSettings is not null :{}",taskSettings);
      // 添加新人任务记录
      TaskDoRecord taskDoRecord = TaskDoRecordBuilder
          .buildTaskDoRecord(TaskSettingsConstant.NEW_USER_TASK,subType, userId);
      taskDoRecordMapper.insertSelective(taskDoRecord);
      // 添加新人任务收益
      UserIncome userIncome = UserIncomeBuilder.buildNotOrdersRelateUserIncome(
          incomeType,taskSettings.getAwardType(),
          Long.valueOf(taskSettings.getAwardNum()),userId
      );
      userIncomeMapper.insertSelective(userIncome);
      userHelper.pluUserVirtualMoneyByType(taskSettings,userId);
    }
  }

  /**
   * 用户名密码登录
   *
   * @param loginInfo
   * @param response
   * @param subject
   * @return
   */
  @Override
  public UserPersonalCenterResponse userNamePasswordLogin(
      UserDto loginInfo,
      HttpServletRequest request,
      HttpServletResponse response,
      Subject subject) {

    // 生成WeixinToken
    UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken();
    usernamePasswordToken.setUsername(loginInfo.getAccount());
    usernamePasswordToken.setPassword(loginInfo.getPassword());
    logger.debug("Login UsernamePasswordToken is : {}", usernamePasswordToken);
    // 登陆
    subject.login(usernamePasswordToken);
    logger.debug("Shiro Login success");
    // 生成token并且设置到header中
    generateTokenAndSetIngoHeader(response, subject,UserContant.APP_LOGIN_TYPE);
    return getAndUpdateLoginMessage(subject,request,loginInfo);
  }

  /**
   * 微信登陆
   *
   * @param loginInfo
   * @param response
   * @param subject
   * @return
   */
  @Override
  public UserPersonalCenterResponse weixinLogin(
      UserDto loginInfo,
      HttpServletRequest request,
      HttpServletResponse response,
      Subject subject) {
    // 生成WeixinToken
    WeixinToken weixinToken = new WeixinToken();
    weixinToken.setUserName(null);
    weixinToken.setOpenId(loginInfo.getOpenId());
    logger.debug("Login WeixinToken is : {}", weixinToken);
    // 登陆
    subject.login(weixinToken);
    logger.debug("Shiro Login success");
    // 生成token并且设置到header中
    generateTokenAndSetIngoHeader(response, subject,UserContant.APP_LOGIN_TYPE);
    return getAndUpdateLoginMessage(subject,request,loginInfo);
  }

  private UserPersonalCenterResponse getAndUpdateLoginMessage(
      Subject subject,
      HttpServletRequest request,
      UserDto loginInfo
  ){
    UserDto userDto = (UserDto) subject.getPrincipal();
    UserPersonalCenterResponse data = getPersonalCenterMessage(userDto.getUserId());
    User user = new User();
    user.setUserId(userDto.getUserId());
    user.setLastLoginTime(new Date());
    user.setLastLoginIp(IpUtil.getIpAddress(request));
    user.setCurrentRegistrationId(loginInfo.getCurrentRegistrationId());
    user.setLoginPlatform(loginInfo.getLoginPlatform());
    userMapper.updateUser(user);
    User user1 = userMapper.selectById(userDto.getUserId());
    data.setAreaCode(user1.getAreaCode());
    data.setPrivacyProtection(user1.getPrivacyProtection());
    data.setLoginPlatform(user.getLoginPlatform());
    return data;
  }


  /**
   * 根据用户的电话号码从数据库或者用户信息
   * 用户手机短信登陆验证
   *
   * @param phone
   * @return
   */
  @Override
  public UserDto getUserDtoInfoForPhoneLogin(String phone) {
    UserDto user = userMapper.selectUserDtoInfoByPhone(phone);
    String key = RedisConstant.MOBILE_CODE_CUSTOMER_NO_LOGIN_PREFIX + phone;
    String mobileCode = stringRedisTemplate.opsForValue().get(key);
    logger.debug("mobileCode is : {}", mobileCode);
    user.setMobileCode(mobileCode);
    user.setPhone(phone);
    user.setEncryptPwd(EncryptUtil.encryptPassword(mobileCode));
    return user;
  }

  /**
   * 微信登陆时，查看用户是否存在
   * 如果不存在，则添加进入数据库
   * 并且通知客户端进行手机绑定
   *
   * @param
   */
  @Override
  public UserDto getUserInfoForWeixinLogin(String openId) {
    return userMapper.selectUserDtoInfoByOpenId(openId);
  }

  /**
   * 账号密码登陆
   *
   * @param phone
   * @return
   */
  @Override
  public UserDto getUserDtoInfoForUserNamePasswordLogin(String phone) {
    return userMapper.selectUserDtoInfoForPasswordLogin(phone);
  }


  @Override
  public UserRelationIdResponse generateRelationAndSpecialId(
      String sessionKey,
      long userId
  ) {
    UserRelationIdResponse userRelationIdResponse = new UserRelationIdResponse();
    //TODO 获取渠道id, 在util里处理了异常
    TbkScPublisherInfoSaveResponse rsp1 =
        TaobaoUtil.getRelationId(sessionKey);
    TbkScPublisherInfoSaveResponse rsp2 =
        TaobaoUtil.getSpecialId(sessionKey);
    logger.debug("TbkScPublisherInfoSaveResponse from tabao is : {}", rsp1);
    logger.debug("TbkScPublisherInfoSaveResponse from tabao is : {}", rsp2);
    // 更新用户的渠道id和会员运营id信息
    User user = new User();
    user.setRelationId(rsp1.getData().getRelationId());
    user.setSpecialId(rsp2.getData().getSpecialId());
    user.setUserId(userId);
    // 更新relationId 到数据库
    userMapper.updateUser(user);
    userRelationIdResponse.setRelationId(rsp1.getData().getRelationId());
    userRelationIdResponse.setSpecialId(rsp2.getData().getSpecialId());
    return userRelationIdResponse;
  }

  @Override
  public ResponseResult<User> selectAllUserInfoForTestByPhone(String phone) {
    ResponseResult<User> responseResult = new ResponseResult<>();
    User user = userMapper.selectAllUserInfoForTestByPhone(phone);
    responseResult.setData(user);
    return responseResult;
  }

  @Override
  public ResponseResult<Void> deleteUserInfoForTestByPhone(String phone) {
    ResponseResult<Void> responseResult = new ResponseResult<>();
    User user = userMapper.selectUserByPhone(phone);
    if (user == null) {
      logger.debug("用户不存在");
      responseResult.setStatus(StatusCode.USER_NOT_EXISTS.getCode());
      responseResult.setMsg("用户不存在");
    } else {
      userMapper.deleteUserInfoForTestByPhone(phone);
    }
    return responseResult;
  }

  /**
   * 生成验证码
   *
   * @param phone
   * @param type
   * @return
   */
  public String generateValidCodeByType(String phone, int type,HttpServletRequest request) {

      logger.debug("phone received from request is : {}", phone);
      logger.debug("type received from request is : {}", type);

      // 生成六位数字验证码
      String mobileCode = generateMobileCode();
      logger.debug("mobileCode is : {}", mobileCode);
      String key = MobileCodeMapper.getRedisValidCodeKeyPrefixByType(type) + phone;
      MobileCodeInformation information = informationHelper.getMobileCodeInformation(phone,type,mobileCode);
    // 发送验证码
    try {

//      limitAccessFrequency(request,phone);
        // 先往redis存放验证码信息，再发送给客户
      stringRedisTemplate.opsForValue().set(key, mobileCode, RedisConstant.MOBILE_CODE_CUSTOMER_TIME_OUT, TimeUnit.MINUTES);
      SendSmsResponse commonResponse = AliUtil.sendSms(phone, mobileCode);
      logger.debug("redis key is : {}, value is : {}", key, mobileCode);
      informationHelper.insertMobileCodeInformation(commonResponse,information);
      return mobileCode;
    } catch (Exception e) {
      logger.debug("sending sms code failed,{}", e);
      stringRedisTemplate.delete(key);

      //短信发送失败
      information.setStatus(2l);
      informationMapper.insertMobileCodeInformation(information);
      throw new BusinessException(StatusCode.MOBILE_CODE_SEND_ERROR);
    }
  }

  /**
   * 生成国际验证码
   *
   * @param phone
   * @param type
   * @return
   */
  public String generateInternationalValidCodeByType(String areaCode,String phone, int type,HttpServletRequest request) {
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append(areaCode);
    stringBuilder.append(phone);
    logger.debug("phone received from request is : {}", phone);
    logger.debug("type received from request is : {}", type);
    // 生成六位数字验证码
    String mobileCode = generateMobileCode();
    logger.debug("mobileCode is : {}", mobileCode);
    String key = MobileCodeMapper.getRedisValidCodeKeyPrefixByType(type) + phone;
    MobileCodeInformation information = informationHelper.getMobileCodeInformation(phone,type,mobileCode);
    // 发送验证码
    try {
//      limitAccessFrequency(request,phone);
      // 先往redis存放验证码信息，再发送给客户
      stringRedisTemplate.opsForValue().set(key, mobileCode, RedisConstant.MOBILE_CODE_CUSTOMER_TIME_OUT, TimeUnit.MINUTES);
      SendSmsResponse commonResponse = AliUtil.sendInternationalSms(stringBuilder.toString(), mobileCode);
      informationHelper.insertMobileCodeInformation(commonResponse,information);
      logger.debug("redis key is : {}, value is : {}", key, mobileCode);
      return mobileCode;
    } catch (Exception e) {
      logger.debug("sending sms code failed,{}", e);
      stringRedisTemplate.delete(key);
      //短信发送失败
      information.setStatus(2l);
      informationMapper.insertMobileCodeInformation(information);
      throw new BusinessException(StatusCode.MOBILE_CODE_SEND_ERROR);
    }
  }


  private void limitAccessFrequency(HttpServletRequest request,String phone){
    //限制访问频率
    String userIp = request.getRemoteAddr();
    ConcurrentHashMap<String,Long> ipMap = new ConcurrentHashMap<>();
    if(ipList!=null && !ipList.isEmpty()){
      for(ConcurrentHashMap<String,Long> myMap : ipList) {
        if(myMap.get(userIp) != null) {
          //同一IP15秒内只能提交一次
          if(System.currentTimeMillis() - myMap.get(userIp) < 15 * 1000){
            myMap.put(phone,System.currentTimeMillis());
            throw new RuntimeException("请求过于频繁");
          }
        }
      }
      if(ipList.size()==10) {
        //放满10次请求 清空一次
        ipList.clear();
      }
    }
    ipMap.put(userIp,System.currentTimeMillis());
    ipList.add(ipMap);
  }


  public ResponseResult<UserAlipayResponse> getAliPayMessage(Long userId) {
    ResponseResult<UserAlipayResponse> responseResult = new ResponseResult<>();
    UserAlipayResponse userAlipayResponse = new UserAlipayResponse();
    logger.debug("userId is : {}", userId);
    User user = userMapper.selectAliPayMessageById(userId);
    userAlipayResponse.setAlipayAccount(user.getAlipayAccount());
    userAlipayResponse.setRealName(user.getRealName());
    responseResult.setData(userAlipayResponse);
    logger.debug("responseResult is : {}",responseResult);
    return responseResult;
  }

  @Override
  public UserPersonalCenterResponse getPersonalCenterMessage(Long userId) {
    logger.debug("user id is: {}",userId);
    UserPersonalCenterResponse rsp = new UserPersonalCenterResponse();
    //用户表存储的信息
    User user = userMapper.selectById(userId);
    logger.debug("user is : {}",user);
    Long uit = user.getUserIntgeralTreasure();
    logger.debug("uit is : {}",uit);
    //TODO
    rsp.setUserAmount(caculateUserAmount(uit,user.getUserAmount()));
    rsp.setUserId(userId);
    rsp.setUserNickName(user.getUserNickName());
    rsp.setHeadImageUrl(user.getUserHeadImage());

    String startTime = DateUtil.getTodayStartTime();
    String endTime = DateUtil.getTomorrowStartTime();
    logger.debug("startTime and endTime is : {}, {}",startTime,endTime);
    BigDecimal totalIncome = userIncomeMapper.selectUserTotalIncomeMessage(userId);
    BigDecimal todayIncome = userIncomeMapper.selectUserTodayIncomeMessage(userId,startTime,endTime);
    BigDecimal freezeMoney = userIncomeMapper.selectFreezeMoney(userId);

    UserGradeRsp userGradeRsp = userGradeHelper.getUserGradeRsp(user.getUserGradeId());

    logger.debug("totalIncome and todayIncome is : {},{}",totalIncome,todayIncome);
    rsp.setTotalIncome(totalIncome.setScale(2,BigDecimal.ROUND_HALF_UP).toString());
    rsp.setTodayIncome(todayIncome.setScale(2,BigDecimal.ROUND_HALF_UP).toString());
    rsp.setFreezeMoney(freezeMoney.setScale(2,BigDecimal.ROUND_HALF_UP).toString());
    rsp.setUserPhone(user.getPhone());
    rsp.setRealName(user.getRealName());
    rsp.setAlipayAccount(user.getAlipayAccount());
    rsp.setRelationId(user.getRelationId());
    rsp.setSpecialId(user.getSpecialId());
    rsp.setTaobaoUserId(user.getTaobaoUserId());
    rsp.setUserGrade(userGradeRsp);
    rsp.setUserRegisterTime(user.getUserRegisterTime());
    rsp.setUserIntgeral(user.getUserIntgeral());
    rsp.setUserStatus(user.getUserStatus());
    rsp.setLoginPlatform(user.getLoginPlatform());
    logger.debug("rsp is : {]",rsp);
    return rsp;
  }

  private String caculateUserAmount(Long uit,BigDecimal am){
    uit = uit == null ? 0L : uit;
    BigDecimal uitDecimal = new BigDecimal(String.valueOf(uit))
        .divide(new BigDecimal("100"))
        .setScale(OrdersConstant.SCALE,BigDecimal.ROUND_HALF_UP);
    BigDecimal amount = uitDecimal.add(am);
    return amount.toString();
  }

  @Override
  public void updateAlipayAccount(UserRequest userRequest, Long userId) {
    logger.debug("received UserRequest is: {}",userRequest);
    User user = userMapper.selectById(userId);
    String previousAliAcount = user.getAlipayAccount();

    if (!userRequest.getAlipayAccount().equals(previousAliAcount)){
      // 校验支付宝是否已经被其他用户绑定
      List<User> users = userMapper.selectUserByAlipayAccount(userRequest.getAlipayAccount());
      if (users.size() > 0 || users == null){
        Long dbUserId = null;
        String userName = null;
        String phone = null;
        for (User user1 : users) {
          dbUserId = user1.getUserId();
          userName = user1.getUserNickName();
          phone = user1.getPhone();
        }

        throw new BusinessException("支付宝重复绑定,已绑定的用户信息为：" +
                "用户id:"+dbUserId +
                ";用户名:"+ userName+
                ";手机号:"+phone
                ,StatusCode.ALIPAY_ACCOUNT_AUTH_FAIL);
      }
    }
    logger.debug("User phone is: {}",user.getPhone());
    // 获取验证码
    String key = RedisConstant.MOBILE_CODE_CUSTOMER_ALIPAY_BIND_PREFIX + user.getPhone();
    logger.debug("key is : {}",key);
    String mobileCode = stringRedisTemplate.opsForValue().get(key);
    logger.debug("value is: {}",mobileCode);
    if(!userRequest.getMobileCode().equals(mobileCode)){
      throw new MobileCodeNotRightException();
    }
    updateUser(userRequest,userId);
    // 更新成功，删除验证码
    stringRedisTemplate.delete(key);

    // 如果先前没有绑定支付宝
    if (StringUtils.isEmpty(previousAliAcount)){
      // 如果有新人任务配置, 那么添加新人任务完成记录和奖励用户
      addNewUserTaskDoAndUserIncomeRecord(
          TaskSettingsConstant.BIND_ALI_ACCOUNT,
          user.getUserId(),
          UserIncomeConstant.BIND_ALICOUNT_AWAED_TYPE
      );
    }
  }

  @Override
  public void updatePhone(UserRequest userRequest, Long userId) {
    logger.debug("received UserRequest is : {}",userRequest);
    // 校验要更新的手机号是否已经被注册
    User dbUser = userMapper.selectById(userId);
    if (!dbUser.getPhone().equals(userRequest.getUserPhone())) {
      User user = userMapper.selectUserByPhone(userRequest.getUserPhone());
      if (user != null) {
        throw new BusinessException("手机号重复绑定,已绑定的用户信息为：" +
                "用户id:"+user.getUserId()
                + ";用户名:"+user.getUserNickName(), StatusCode.PHONE_HASH_BIND);
      }
    }
    // 对比验证码是否正确
    String key = RedisConstant.MOBILE_CODE_CUSTOMER_NEW_PHONE_PREFIX + userRequest.getUserPhone();
    logger.debug("key is : {}",key);
    String mobileCode = stringRedisTemplate.opsForValue().get(key);
    if(!userRequest.getMobileCode().equals(mobileCode)){
      throw new MobileCodeNotRightException();
    }
    logger.debug("update Phone success");
    // 更新用户信息
    updateUser(userRequest,userId);
    //清除redis数据库验证码记录
    stringRedisTemplate.delete(key);
  }

  @Override
  public void updatePassword(UserRequest userRequest, Long userId) {
    logger.debug("received UserRequest is : {}",userRequest);
    // 对比验证码是否正确
    String key = RedisConstant.MOBILE_CODE_CUSTOMER_PASSWORD_PHONE_PREFIX + userRequest.getUserPhone();
    String mobileCode = stringRedisTemplate.opsForValue().get(key);
    logger.debug("mobileCode is : {}",mobileCode);
    if(!userRequest.getMobileCode().equals(mobileCode)){
      throw new MobileCodeNotRightException();
    }
    logger.debug("update Password success");
    // 更新用户信息
    updateUser(userRequest,userId);
    //清除redis数据库验证码记录
    stringRedisTemplate.delete(key);
  }

  @Override
  public void findPassword(PasswordRequest passwordRequest) {
    logger.debug("PasswordRequest is : {}",passwordRequest);
    // 根据电话查询用户
    String key = RedisConstant.MOBILE_CODE_CUSTOMER_NO_LOGIN_PREFIX + passwordRequest.getUserPhone();
    String mobileCode = stringRedisTemplate.opsForValue().get(key);
    logger.debug("mobileCode from redis is : {}",mobileCode);
    if(!passwordRequest.getMobileCode().equals(mobileCode)){
      throw new MobileCodeNotRightException();
    }
    User user = userMapper.selectUserByPhone(passwordRequest.getUserPhone());
    // 手机号不存在
    if(user == null){
      throw new PhoneNotExistsException();
    }
    User u = new User();
    u.setUserId(user.getUserId());
    String plainText = passwordRequest.getPassword();
    user.setUserPassword(EncryptUtil.encryptPassword(plainText));
    logger.debug("password is : {}",user.getUserPassword());
//    userMapper.updateUserPassword(user);
    userMapper.updateUser(u);
  }

  @Override
  public UserFansListResponse getOneLevelFansDetail(
      Integer pageNo,
      Integer pageSize,
      Long userId,
      String userNameOrPhone) {
    logger.debug("pageNo is : {}",pageNo);
    logger.debug("pageSize is :{}",pageSize);
    User user = userMapper.selectById(userId);
    UserFansListResponse userFansListResponse = new UserFansListResponse();
    userFansListResponse.setTotalFansNum(user.getTotalFansNum());
    // 获取一级粉丝数
    PageHelper.startPage(pageNo, pageSize);
    List<UserFansDetailInfo> page = userMapper.selectOneLevelFansInfo(user.getUserId(),userNameOrPhone);
    logger.debug("one level page is : {}", page);
    PageInfo<UserFansDetailInfo> pageInfo = new PageInfo<>(page);
    logger.debug("pageInfo is:{}", pageInfo);
    userFansListResponse.setOneLevelFans(pageInfo);
    return userFansListResponse;
  }

  @Override
  public UserFansListResponse getSecondLevelFansDetail(
      Integer pageNo,
      Integer pageSize,
      Long userId,
      String userNameOrPhone) {
    logger.debug("pageNo is : {}",pageNo);
    logger.debug("pageSize is :{}",pageSize);
    User user = userMapper.selectById(userId);
    UserFansListResponse userFansListResponse = new UserFansListResponse();
    userFansListResponse.setTotalFansNum(user.getTotalFansNum());
    // 获取二级粉丝数
    PageHelper.startPage(pageNo, pageSize);
    List<UserFansDetailInfo> page = userMapper.selectSecondLevelFansInfo(user.getUserId(),userNameOrPhone);
    logger.debug("two level page is : {}", page);
    PageInfo<UserFansDetailInfo> pageInfo = new PageInfo<>(page);
    logger.debug("pageInfo is:{}", pageInfo);
    userFansListResponse.setSecondLevelFans(pageInfo);
    return userFansListResponse;
  }


  @Override
  public ResponseResult<UserIncomeRecordResponse> getUserIncomeRecordDetail(Long userId) {
    logger.debug("userId is : {}",userId);
    User user = userMapper.selectById(userId);
    logger.debug("user is : {}",user);
    ResponseResult<UserIncomeRecordResponse> responseResult = new ResponseResult<>();
    // 这个月时间端
    String thisMonthStartTime = DateUtil.getThisMonthStartDay();
    String nextMonthStartTime = DateUtil.getNextMonthStartDay();
    String lastMonthStartTime = DateUtil.getLastMonthStartDay();
    logger.debug("thisMonthStartTime and nextMonthStartTime and lastMonthStartTime  is : {}, {}, {}",
        thisMonthStartTime,nextMonthStartTime,lastMonthStartTime);
    String thisDayStartTime = DateUtil.getTodayStartTime();
    String nextDayStartTime = DateUtil.getTomorrowStartTime();
    logger.debug("thisDayStartTime and nextDayStartTime is : {},{}",thisDayStartTime,nextDayStartTime);
    String lastDayStartTime = DateUtil.getLastDayStartTime();
    logger.debug("lastDayStartTime is : {}",lastDayStartTime);
    UserIncomeRecordResponse userIncomeRecordResponse =
        userIncomeMapper.selectUserIncomeRecordDetail(
            thisMonthStartTime,
            nextMonthStartTime,
            lastMonthStartTime,
            thisDayStartTime,
            nextDayStartTime,
            lastDayStartTime,
            userId
        );
    if(userIncomeRecordResponse == null){
      userIncomeRecordResponse = new UserIncomeRecordResponse();
    }
    BigDecimal amount = new BigDecimal(caculateUserAmount(user.getUserIntgeralTreasure(),user.getUserAmount()));
    userIncomeRecordResponse.setUserAmount(amount);
    logger.debug("UserIncomeRecordResponse is : {}",userIncomeRecordResponse);
    responseResult.setData(userIncomeRecordResponse);
    return responseResult;
  }

  @Override
  public PrivilegeLinkAndTpwdResponse getPrivilegeLinkAndTpwd(
      boolean flag,
      String goodsId,
      String taobaoUserId,
      String taobaoUserName,
      String text,
      String logo,
      String accessToken,
      Long relationId,
      Long specialId,
      Long userId,
      String extra
  ) {

    User user = userMapper.selectById(userId);
    logger.debug("relationId and specialId is: {},{}",relationId,specialId);
    logger.debug("taobaoUserId is : {}",taobaoUserId);
    logger.debug("user is : {}",user);
    // 如果flag == true , 查看淘宝授权是否已经发生更换
    if(flag){
      if(!relationId.equals(user.getRelationId())){
        throw new BusinessException("淘宝授权已发生更换",StatusCode.TAOBAO_AUTH_CHANGE);
      }
    }
    if(!flag){
      // 如果渠道id为空，那么生成渠道id
      relationId = TaobaoUtil.checkAndGetRelationId(relationId,accessToken);
      // 如果会员运营id为空, 那么生成会员运营id
      specialId = TaobaoUtil.checkAndGetSpecialId(specialId,accessToken);
      // 新用户任务收益
      addNewUserTaskDoAndUserIncomeRecord(
          TaskSettingsConstant.TAOBAO_AUTH,
          user.getUserId(),
          UserIncomeConstant.TAOBAO_AUTH_AWAED_TYPE
      );
    }
    logger.debug("taobaoUserId is : {}",taobaoUserId);
    // 如果relationId 或者specialId有一个为空,那么需要进行绑定
    checkIfBindTaobaoBefore(flag,relationId,specialId,userId);
    logger.debug("taobaoUserId is : {}",taobaoUserId);
    // 转链
    PrivilegeLinkAndTpwdResponse privilegeLinkAndTpwdResponse  =
        doGetPrivilegesLink(goodsId,relationId,taobaoUserId,text,logo,specialId);
    logger.debug("taobaoUserId is : {}",taobaoUserId);
    // 更新用户淘宝账号信息
    updateUserTaoBaoInfo(user,taobaoUserId,relationId,specialId,taobaoUserName);
    logger.debug("taobaoUserId is : {}",taobaoUserId);
    return privilegeLinkAndTpwdResponse;
  }

  private void checkIfBindTaobaoBefore(boolean flag,Long relationId,Long specialId, Long userId){

    if(!flag){
      User u = userMapper.selectUserByRelationIdOrSpecialId(relationId,specialId);
      // 如果先前已经有不同用户绑定了这个淘宝账号，那么抛出异常
      if(u != null && !u.getUserId().equals(userId)){
        TaobaoAuthFailRsp rsp = new TaobaoAuthFailRsp();
        rsp.setUserId(u.getUserId());
        rsp.setPhone(u.getPhone());
        rsp.setUserNickName(u.getUserNickName());
        throw new TaobaoAuthMultiException("重复绑定淘宝账号",
            StatusCode.REPEAT_BIND_TAOBAO_ACCOUNT, rsp
            );
      }
    }
  }

  private void updateUserTaoBaoInfo(
      User user, String taobaoUserId,
      Long relationId, Long specialId,
      String taobaoUserName
  ){
    if(user.getTaobaoUserId() == null || user.getRelationId() == null
        || user.getSpecialId() == null|| StringUtils.isEmpty(user.getTaobaoUserName())){
      User u = new User();
      u.setUserId(user.getUserId());
      if(StringUtils.isEmpty(user.getTaobaoUserId()) ||
          StringUtils.isEmpty(user.getTaobaoUserId().trim())){
        u.setTaobaoUserId(taobaoUserId);
      }
      if(StringUtils.isEmpty(user.getTaobaoUserName()) ||
          StringUtils.isEmpty(user.getTaobaoUserName().trim())){
        u.setTaobaoUserName(taobaoUserName);
      }
      if(user.getRelationId() == null){
        u.setRelationId(relationId);
      }
      if(user.getSpecialId() == null){
        u.setSpecialId(specialId);
      }
      u.setIsAuth(UserContant.IS_AUTH);
      userMapper.updateUser(u);
    }
  }

  private PrivilegeLinkAndTpwdResponse doGetPrivilegesLink(
      String goodsId, Long relationId,
      String taobaoUserId, String text,
      String logo, Long specialId){
    // 获取商品转链信息
    DingdanxiaRsp<DingdanxiaLink> dingdanxiaRsp =
        DingdanxiaUtil.getPrivilegeLink(goodsId, String.valueOf(relationId));
    // 获取转链信息失败
    if(dingdanxiaRsp == null || dingdanxiaRsp.getData() == null){
      throw  new BusinessException(StatusCode.PRIVILEGE_LINK_GENERATE_FAIL);
    }

    DingdanxiaLink dingdanxiaLink = dingdanxiaRsp.getData();
    String url = confirmTpwdUrl(dingdanxiaLink);
    url = url + "&relationId=" + relationId;
    logger.debug("url is : {}",url);

    TpwdRequest tpwdRequest = new TpwdRequest();
    tpwdRequest.setUser_id(taobaoUserId);
    tpwdRequest.setText(text);
    tpwdRequest.setUrl(url);
    tpwdRequest.setLogo(logo);
    String tpwd = TaobaoUtil.getTpwd(tpwdRequest);

//    TklCreateReq req = new TklCreateReq();
//    req.setUser_id(taobaoUserId);
//    req.setText(text);
//    req.setUrl(url);
//    req.setLogo(logo);
//    DingdanxiaRsp<TklCreateRsp> rsp = DingdanxiaUtil.tklCreate(req);

    PrivilegeLinkAndTpwdResponse privilegeLinkAndTpwdResponse = new PrivilegeLinkAndTpwdResponse();
    privilegeLinkAndTpwdResponse.setGoodsId(goodsId);
    privilegeLinkAndTpwdResponse.setCouponClickUrl(dingdanxiaLink.getCoupon_click_url());
    privilegeLinkAndTpwdResponse.setItemUrl(dingdanxiaLink.getItem_url());
    privilegeLinkAndTpwdResponse.setRelationId(relationId);
    privilegeLinkAndTpwdResponse.setSpecialId(specialId);
//    privilegeLinkAndTpwdResponse.setTpwd(rsp.getData().getData().get("model"));
    privilegeLinkAndTpwdResponse.setTpwd(tpwd);
    privilegeLinkAndTpwdResponse.setCoupon(dingdanxiaLink.getCoupon());
    return privilegeLinkAndTpwdResponse;
  }

  private String confirmTpwdUrl(DingdanxiaLink dingdanxiaLink){
    String coupon = dingdanxiaLink.getCoupon();
    String url = dingdanxiaLink.getCoupon_click_url();
    // 如果coupon 是 0,那么选择item_url
    if(StringUtils.isEmpty(coupon) || "0".equals(coupon)){
      url = dingdanxiaLink.getItem_url();
    }
    return url;
  }

  @Override
  public List<PrivilegeLinkAndTpwdResponse> getMultiPrivilegeLinkAndTpwd(
      MultiPrivilegeLinkRequest privilegeLinkRequest, Long userId){

    Long relationId = privilegeLinkRequest.getRelationId();
    Long specialId = privilegeLinkRequest.getSpecialId();
    // 如果渠道id为空，那么生成渠道id
    logger.debug("relationId and specialId is: {},{}",relationId,specialId);
    // 如果渠道id为空，那么生成渠道id
    relationId = TaobaoUtil.checkAndGetRelationId(relationId,privilegeLinkRequest.getAccessToken());
    // 如果会员运营id为空, 那么生成会员运营id
    specialId = TaobaoUtil.checkAndGetSpecialId(specialId,privilegeLinkRequest.getAccessToken());

    // 如果relationId 或者specialId有一个为空,那么需要进行绑定
    checkIfBindTaobaoBefore(privilegeLinkRequest.isFlag(),relationId,specialId,userId);

    List<PrivilegeLinkAndTpwdResponse> responses = new ArrayList<>();
    for(PrivilegeLinkProductData productData: privilegeLinkRequest.getData()){
      responses.add(doGetPrivilegesLink(
          productData.getGoodsIds(),
          relationId,
          privilegeLinkRequest.getUserId(),
          productData.getText(),
          productData.getLogo(),
          specialId
      ));
    }

    return responses;
  }

  public CheckActivityConditionRsp checkIfUserCanBuyActivity(
      Long userId,
      String goodsId,
      boolean flag,
      String access_token,
      String taobaoUserId,
      String userName,
      Integer activityId,
      Integer productRepoId,
      ActivityProductCondition condition,
      Integer itemType){

    CheckActivityConditionRsp rsp = new CheckActivityConditionRsp();
    TaobaoAuthFailRsp taobaoAuthFailRsp = new TaobaoAuthFailRsp();

    try {
      logger.debug("this user is : {}",userId);
      User user = userMapper.selectById(userId);
      logger.debug("this user is : {}",user);
      // 如果flag 为false, 那么获取用户relationId 和specialId
      // 就算不允许购买,也要返回relationId 和 specialId
      // 如果是淘宝商品，则需要进行淘宝授权
      if (itemType == null || itemType == 0) {
        Long relationId = user.getRelationId(), specialId = user.getSpecialId();
        logger.debug("relationId and specialId is : {},{}", relationId, specialId);
        if (!flag) {
          // 如果渠道id为空，那么生成渠道id
          relationId = TaobaoUtil.checkAndGetRelationId(null, access_token);
//        relationId = 2425221255l;
          // 如果会员运营id为空, 那么生成会员运营id
          specialId = TaobaoUtil.checkAndGetSpecialId(null, access_token);
//        specialId = 2425219245l;
          // 检查之前是否已经绑定过淘宝账号
          checkIfBindTaobaoBefore(false, relationId, specialId, userId);
          // 更新淘宝账户信息
          updateUserTaoBaoInfo(user, taobaoUserId, relationId, specialId, userName);
          // 新用户任务收益
          addNewUserTaskDoAndUserIncomeRecord(
                  TaskSettingsConstant.TAOBAO_AUTH,
                  user.getUserId(),
                  UserIncomeConstant.TAOBAO_AUTH_AWAED_TYPE
          );
        }
        logger.debug("relationId and specialId is : {},{}", relationId, specialId);
        rsp.setRelationId(relationId);
        rsp.setSpecialId(specialId);
      }
      String nowTime = DateUtil.getNowStr();
      LocalDateTime now = DateUtil.getLocationDateTime(nowTime);
      logger.debug("endTime is:{}", nowTime);
      logger.debug("Condition is : {}", condition);
      // 0元购活动检查
      if (activityId.equals(ActivityConstant.ZERO_PURCHASE_ACTIVITY)) {
        // 根据活动id 和 商品id获取活动商品记录
        ActivityProduct activityProduct = getActivityProduct(activityId, goodsId);
        logger.debug("ActivityProduct is : {}", activityProduct);
        checkZeroPurchaseActivity(activityProduct, condition, user, now, nowTime);
        // 检查是否已经卖完了
        checkLimitNum(activityProduct.getLimitNum(), goodsId, activityId);
      }
      // 自定义活动检查
      if (activityId.equals(ActivityConstant.CUSTOM_COMMAND_ACTIVITY)) {
        checkCustCommandActivity(user, now);
      }
      logger.debug("itemType is : {}",itemType);
      // 淘宝转链
      if (itemType == null || itemType == 0) {
        getActivityProductPrivilegeLink(goodsId, rsp);
      }
      if (itemType != null) {
        // 拼多多转链
        if (itemType == 1) {
          logger.debug("拼多多转链");
          getPddConvert(userId, goodsId, rsp);
        }
      }
      // 添加点击浏览记录
      addActivityBrowseProductRecord(userId, activityId, goodsId, condition, productRepoId);


    }catch (Exception ex){
      ex.printStackTrace();
      rsp.setIs_allow(false);
      rsp.setReason(ex.getMessage());
      if (ex instanceof TaobaoAuthMultiException){
        Object object = ((TaobaoAuthMultiException) ex).getObj();
        logger.debug("this object is : {}",object);
        rsp.setTaobaoAuthFailRsp(object);
      }
    }

    return rsp;
  }

  private void checkZeroPurchaseActivity(
      ActivityProduct activityProduct,
      ActivityProductCondition condition,
      User user, LocalDateTime now,
      String nowTime){
    // 今日邀请
    checkZeroOrderNumByQuqlType(activityProduct,user.getUserId());
    // 检查用户级别是否符合要求
    checkUserLevel(condition,user);
    // 检查指定天数内订单量是否满足要求
    checkSetTimeAndNumAndScene(condition,user,now,nowTime);
    // 检查注册天数
    checkJoinTime(condition,user,now);
    // 检查当天邀请人数是否符合要求
    checkInviteNum(condition,user);
  }

  private void checkZeroOrderNumByQuqlType(ActivityProduct activityProduct, Long userId){

    if(ActivityProductConstant.NEW_USER == activityProduct.getQualType()){
      OrderActivityRecord orderActivityRecord = orderActivityRecordMapper.selectCustRecord(userId);
      if(orderActivityRecord != null){
        throw  new BusinessException("您已购买过自定义密令商品",StatusCode.AVTIVITY_ERROR);
      }
      orderActivityRecord = orderActivityRecordMapper.selectZeroNewUserRecord(userId);
      if(orderActivityRecord != null){
        throw  new BusinessException("您已购买过新用户专享商品",StatusCode.AVTIVITY_ERROR);
      }
    }

    if(ActivityProductConstant.CONDITION == activityProduct.getQualType()){
      OrderActivityRecord orderActivityRecord = orderActivityRecordMapper.selectZeroConditionRecord(userId);
      if(orderActivityRecord != null){
        throw  new BusinessException("您已购买过条件购买商品",StatusCode.AVTIVITY_ERROR);
      }
    }

    if(ActivityProductConstant.TODAY_INVITE == activityProduct.getQualType()){
      OrderActivityRecord orderActivityRecord = orderActivityRecordMapper.selectZeroTodayInviteUserRecord(userId);
      if(orderActivityRecord != null){
        throw  new BusinessException("您已购买过今日邀请商品",StatusCode.AVTIVITY_ERROR);
      }
    }

  }

  private void checkCustCommandActivity(User user, LocalDateTime now){

    // 检查是否是注册72小时的新用户
    LocalDateTime registerTime = DateUtil.transferDateToLocalDateTime(user.getUserRegisterTime());
    LocalDateTime hoursAfter = registerTime.plusHours(72L);
    if(now.isAfter(hoursAfter)){
      throw  new BusinessException("注册时间超过三天",StatusCode.AVTIVITY_ERROR);
    }
    // 根据用户id检查用户订单数
    Long count = ordersMapper.selectCountByUserId(user.getUserId());
    if(count != null && count >= 1L){
      throw  new BusinessException("您已经下过单",StatusCode.AVTIVITY_ERROR);
    }
    OrderActivityRecord orderActivityRecord = orderActivityRecordMapper.selectZeroNewUserRecord(user.getUserId());
    if(orderActivityRecord != null){
      throw  new BusinessException("您已购买过新用户专享商品",StatusCode.AVTIVITY_ERROR);
    }
  }

  private void checkLimitNum(Integer limitNum, String goodsId, Integer activityId){
    if(limitNum == null){
      return ;
    }
    if(limitNum == 0){
      throw  new BusinessException("商品已经卖完",StatusCode.AVTIVITY_ERROR);
    }
    Long currentNum = ordersMapper.selectCountByActivityIdAndGoodsId(goodsId,activityId);
    if(currentNum > limitNum){
      throw  new BusinessException("商品已经卖完",StatusCode.AVTIVITY_ERROR);
    }
  }

  private void getActivityProductPrivilegeLink(String goodsId,CheckActivityConditionRsp rsp){
    // 获取商品转链信息
    DingdanxiaRsp<DingdanxiaLink> dingdanxiaRsp =
        DingdanxiaUtil.getAcvitityProductPrivilegeLink(goodsId);
    // 获取转链信息失败
    checkDingdanxiaResponse(dingdanxiaRsp);
    DingdanxiaLink dingdanxiaLink = dingdanxiaRsp.getData();
    rsp.setIs_allow(true);
    rsp.setCoupon(dingdanxiaLink.getCoupon());
    rsp.setCouponClickUrl(dingdanxiaLink.getCoupon_click_url());
    rsp.setItemUrl(dingdanxiaLink.getItem_url());
    rsp.setGoodsId(goodsId);
  }

  private void getPddConvert(Long userId,String goodsId,CheckActivityConditionRsp rsp) throws IOException {
    PddConvertReq req = new PddConvertReq();
    req.setGoods_id_list(goodsId);
    req.setCustom_parameters("activityOrders");
    Object pddConvert = userJdPidHelper.getPddConvert(req, userId);
    logger.debug("pddConvert is : {}",pddConvert);
    String jsonString = JSON.toJSONString(pddConvert);
    logger.debug("substring is : {}",jsonString);
    PddConvertResponse pddConvertResponse = gson.fromJson(jsonString, PddConvertResponse.class);
    logger.debug("pddConvertResponse is : {}",pddConvertResponse);
    PddConvertRes data = pddConvertResponse.getData();
    rsp.setIs_allow(true);
    rsp.setCouponClickUrl(data.getSchema_url());
    rsp.setItemUrl(data.getSchema_url());
    rsp.setCoupon("0");
    rsp.setGoodsId(goodsId);

  }

  private void addActivityBrowseProductRecord(Long userId,Integer activityId,
      String goodsId,ActivityProductCondition condition,Integer productRepoId)
      throws JsonProcessingException {
    logger.debug("addActivityBrowseProductRecord");
    // 添加点击浏览记录
    ActivityBrowseProduct activityBrowseProduct = new ActivityBrowseProduct();
    activityBrowseProduct.setUserId(userId);
    activityBrowseProduct.setClickTime(new Date());
    activityBrowseProduct.setActivityId(activityId);
    activityBrowseProduct.setGoodsId(Long.valueOf(goodsId));
    if(condition != null){
      ObjectMapper objectMapper = new ObjectMapper();
      activityBrowseProduct.setJson(objectMapper.writeValueAsString(condition));
    }
    activityBrowseProduct.setProductRepoId(productRepoId);
    activityBrowseProductMapper.insertSelective(activityBrowseProduct);
  }

  private ActivityProduct getActivityProduct(Integer activityId, String productId){

    ActivityProduct activityProduct =
        activityProductMapper.selectProductByActivityAndProductId(activityId,productId);
    // 商品过期或者商品不存在
    if(activityProduct == null){
      throw  new BusinessException("商品不存在或者活动过期",StatusCode.AVTIVITY_ERROR);
    }
    return activityProduct;
  }

  private void checkUserLevel(ActivityProductCondition condition,User user){
    if(condition.getUserLevel() != null){
      if(!user.getUserGradeId().equals(condition.getUserLevel())){
        throw new BusinessException("用户等级不满足条件",StatusCode.AVTIVITY_ERROR);
      }
    }
  }

  private void checkSetTimeAndNumAndScene(
      ActivityProductCondition condition,
      User user, LocalDateTime now,
      String endTime){

    if(condition.getSetTime() == null || condition.getSetNum() == null ||
        condition.getScene() == null){
      return;
    }
    String startTime = DateUtil.getDaysBefore(now,condition.getSetTime());
    Long tkStatus = null;
    if(condition.getScene() == 0L){
      tkStatus = OrdersConstant.ACCOUNTING_STATUS;
    }
    if(condition.getScene() == 1L){
      tkStatus = OrdersConstant.PAID_STATUS;
    }
    Long num = ordersMapper.selectCountByTimeAndUser(user.getUserId(), startTime,endTime,tkStatus);
    logger.debug("orders num is : {}",num);
    if(num == null || num < condition.getSetNum()){
      throw new BusinessException("订单数量没有达到要求",StatusCode.AVTIVITY_ERROR);
    }
  }

  private void checkJoinTime(ActivityProductCondition condition,User user, LocalDateTime now){
    if(condition.getJoinTime() != null){

      LocalDateTime registerTime = DateUtil.transferDateToLocalDateTime(user.getUserRegisterTime());
      LocalDateTime daysAfter =  registerTime.plusDays(condition.getJoinTime());
      // 如果当前时间不在范围内
      if(now.isAfter(daysAfter)){
        throw new BusinessException("注册时间超过"+condition.getJoinTime()+"天",StatusCode.AVTIVITY_ERROR);
      }
    }
  }

  private void checkInviteNum(ActivityProductCondition condition,User user){
    if(condition.getInviteNum() != null){
      String startTime = DateUtil.getTodayStartTime();
      String endTime = DateUtil.getTomorrowStartTime();
      Long count = userMapper.selectInviteNumThisDay(startTime,endTime,user.getUserId());
      logger.debug("invite num is:{}",count);
      if(count == null || count<condition.getInviteNum()){
        throw new BusinessException("当天邀请人数没有达到要求",StatusCode.AVTIVITY_ERROR);
      }
    }
  }

  private void checkDingdanxiaResponse(DingdanxiaRsp dingdanxiaRsp){
    if(dingdanxiaRsp == null || dingdanxiaRsp.getData() == null){
      throw  new BusinessException(StatusCode.PRIVILEGE_LINK_GENERATE_FAIL);
    }
  }

  private void updateUser(@RequestBody UserRequest userRequest, Long userId){
    // 更新用户信息
    User user = convertFromUserRequestToUser(userRequest);
    user.setUserId(userId);
    logger.debug("user is : {}",user);
    userMapper.updateUser(user);
    logger.debug("update success");
  }

  private User convertFromUserRequestToUser(UserRequest userRequest){
    User user = new User();
    user.setPhone(userRequest.getUserPhone());
    user.setUserHeadImage(userRequest.getHeadImageUrl());
    user.setUserNickName(userRequest.getUserNickName());
    if(!StringUtils.isEmpty(userRequest.getPassword())){
      String plainText = userRequest.getPassword();
      user.setUserPassword(EncryptUtil.encryptPassword(plainText));
    }
    user.setRealName(userRequest.getRealName());
    user.setAlipayAccount(userRequest.getAlipayAccount());
    return user;
  }

  @Override
  public void rewardUser(Long userId) {

    // 查看是否超过最大次数
    TaskSettings taskSettings = taskSettingsMapper.selectUseSettingsBySubType(TaskSettingsConstant.BROWSE_PRODUCT);
    int maxTime = taskSettings == null ? 1 : taskSettings.getMaxTimes();
    int todayCount = userIncomeMapper.selectTodayCountByType(UserIncomeConstant.BROWSE_AWAED_TYPE,userId);
    if(todayCount >= maxTime){
      throw new BusinessException("今天阅读奖励次数达上限制",StatusCode.BROWSE_AWARD_ERROR);
    }
    Long uit = null , integral = null;
    if(taskSettings.getAwardType() == UserIncomeConstant.UIT_AWARD_TYPE){
      uit = Long.valueOf(taskSettings.getAwardNum());
      userMapper.plusUserUit(Long.valueOf(taskSettings.getAwardNum()),userId);
    }
    if(taskSettings.getAwardType() == UserIncomeConstant.IT_AWARD_TYPE){
      integral = Long.valueOf(taskSettings.getAwardNum());
      userMapper.plusUserIntgeral(integral,userId);
    }
    UserIncome userIncome = UserIncomeBuilder.buildBrowseProductIncome(
        userId, uit, integral,
        taskSettings.getAwardType()
        );
    userIncomeMapper.insertSelective(userIncome);
    TaskDoRecord taskDoRecord = new TaskDoRecord();
    taskDoRecord.setUserId(userId);
    taskDoRecord.setType(TaskSettingsConstant.DAILY_TASK);
    taskDoRecord.setSubType(TaskSettingsConstant.BROWSE_PRODUCT);
    Date date = new Date();
    taskDoRecord.setCreateTime(date);
    taskDoRecord.setUpdateTime(date);
    taskDoRecordMapper.insertSelective(taskDoRecord);
  }

  @Override
  public ProductRepoChoiceRsp decodeSecretAndBindRelation(String sk, Long userId) {

    User user = userMapper.selectById(userId);

    LocalDateTime now = LocalDateTime.now();
    // 根据密令查询密令记录信息
    checkCustCommandActivity(user,now);
    // 如果用户已经有上级
    AppSk appSk = appSkMapper.selectAppSkBySk(sk);
    if(user.getParentUserId() != null){
      if(!String.valueOf(user.getParentUserId()).equals(appSk.getPromoterId())){
        throw  new BusinessException("非已有上级发布的密令",StatusCode.AVTIVITY_ERROR);
      }
    }else{
      User u = new User();
      u.setUserId(userId);
      u.setParentUserId(Long.valueOf(appSk.getPromoterId()));
      userMapper.updateUser(u);
    }
    ProductRepoChoice productRepoChoice = new ProductRepoChoice();
    PageInfo<Product>  pageInfo = customerProductService
        .selectProductRepoChoiceProduct(productRepoChoice,appSk.getCustProductId(),1,20);
    ProductRepoChoiceRsp data = new ProductRepoChoiceRsp();
    data.setActivityId(2);
    data.setProductRepoId(appSk.getCustProductId());
    data.setData(pageInfo);
    return data;
  }

  @Override
  public TaobaoAuthRsp taobaoAuth(Long userId, String taobaoUserId, String userName,
      String accessToken) {

    TaobaoAuthRsp taobaoAuthRsp = new TaobaoAuthRsp();
    taobaoAuthRsp.setAuthSuccess(true);
    try {
      User user = userMapper.selectById(userId);
      // 如果渠道id为空，那么生成渠道id
      Long relationId = TaobaoUtil.checkAndGetRelationId(null,accessToken);
      // 如果会员运营id为空, 那么生成会员运营id
      Long specialId = TaobaoUtil.checkAndGetSpecialId(null,accessToken);
      logger.debug("taobaoAuth relationId is : {}",relationId);
      // 是否已经授权过别的用户
      checkIfBindTaobaoBefore(false,relationId,specialId,userId);
      taobaoAuthRsp.setRelationId(relationId);
      taobaoAuthRsp.setSpecialId(specialId);
      taobaoAuthRsp.setUserId(userId);
      updateUserTaoBaoInfo(user,taobaoUserId,relationId,specialId,userName);
      // 如果有新人任务配置, 那么添加新人任务完成记录和奖励用户
      addNewUserTaskDoAndUserIncomeRecord(
          TaskSettingsConstant.TAOBAO_AUTH,
          user.getUserId(),
          UserIncomeConstant.TAOBAO_AUTH_AWAED_TYPE
      );
    }catch (BusinessException ex){
      logger.debug("auth fail");
      taobaoAuthRsp.setAuthSuccess(false);
      taobaoAuthRsp.setMsg(ex.getMessage());
      if(ex instanceof TaobaoAuthMultiException){
        Object object = ((TaobaoAuthMultiException) ex).getObj();
        taobaoAuthRsp.setAuthUserMsg(object);
      }
    }

    return taobaoAuthRsp;
  }

  @Override
  public void  plusOrReduceVirtualMoney(PlusOrReduceVirMoneyReq req,Long userId) {
    userHelper.pluUserVirtualMoneyAndUserIncomeByType(req,userId);
  }

  @Override
  public Map<String, InviteDetailRsp> selectInviteDetail(Long userId) {

    String now = DateUtil.getNowStr();
    Map<String,Long> validUserMap = userMapper.selectSMACount(userId,now);
    Map<String,Long> buyUserMap = userMapper.selectSMABuyOrderCount(userId,now);
    Map<String,BigDecimal> inviteIncomeMap = userIncomeMapper.selectSMAIncome(userId,now);

    logger.debug("validUserMap is : {}",validUserMap);
    logger.debug("validUserMap is : {}",buyUserMap);
    logger.debug("inviteIncomeMap is : {}",inviteIncomeMap);

    return UserBuilder.buildInviteDetailRspMap(validUserMap,buyUserMap,inviteIncomeMap);
  }

  @Override
  public boolean checkRelationId(Long userId, Long relationId) {
    User user = userMapper.selectById(userId);
    if(user == null){
      throw new BusinessException("用户不存在",StatusCode.INTERNAL_ERROR);
    }
    return relationId.equals(user.getRelationId());
  }

  @Override
  public void weixinAuth(Long userId, String openId) {
    // 根据openId(微信id) 查找用户
    User dbUser = userMapper.selectUserByOpenId(openId);
    // openId 已经被授权（已经记录到数据库），并且授权的不是当前用户
    if(dbUser != null && !dbUser.getUserId().equals(userId)){
      // 这个异常会被全局异常处理器catch到
      throw new BusinessException("微信重复授权",StatusCode.WEIXIN_AUTH_FAIL);
    }
    logger.debug("dbUser is : {}",dbUser);
    logger.debug("userId is : {}",userId);
    // 如果当前用户之前已经授权了同一个openId，直接返回
    if (dbUser != null) {
      if (dbUser.getUserId().equals(userId)) {
        return;
      }
    }
    // 如果openId没被授权，那么保存
    User user = new User();
    user.setUserId(userId);
    user.setOpenId(openId);
    // 如果有新人任务配置, 那么添加新人任务完成记录和奖励用户
    addNewUserTaskDoAndUserIncomeRecord(TaskSettingsConstant.BIND_WECHAT_ACCOUNT,
            user.getUserId(), UserIncomeConstant.WETCHAT_AUTH_AWAED_TYPE);
    userMapper.updateUser(user);
  }

  @Override
  public TokenRsp getNewToken(long userId) {
    String accessToken = JwtUtils.sign(
        String.valueOf(userId), UserContant.APP_LOGIN_TYPE,
        CommonConstant.JWT_SALT,
        CommonConstant.ACCESS_TOKEN_EXPIRE_TIME);
    String refreshToken = JwtUtils.sign(
        String.valueOf(userId), UserContant.APP_LOGIN_TYPE,
        CommonConstant.JWT_SALT,
        CommonConstant.REFRESH_TOKEN_EXPIRE_TIME);
    TokenRsp tokenRsp = new TokenRsp();
    tokenRsp.setAccess_token(accessToken);
    tokenRsp.setRefresh_token(refreshToken);
    return tokenRsp;
  }

  //  @Override
//  public void logoff(Long userId) {
//    User user = new User();
//    user.setUserId(userId);
//    user.setUserStatus(UserContant.USER_STATUS_LOGOFF);
//    userMapper.updateUser(user);
//  }
}
